package com.lagou;

import com.lagou.bean.ConsumerComponent;
import com.lagou.common.Common;
import net.jodah.expiringmap.ExpiringMap;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


public class AnnotationConsumerMain {

    private final static ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 2);
    private final static Object lock = new Object();

    public static void main(String[] args) throws IOException, InterruptedException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
        context.start();
        ConsumerComponent service = context.getBean(ConsumerComponent.class);

        startPrintThead();

        while (true) {
            threadPool.submit(()->{
                service.sayHello("ban");
            });

            threadPool.submit(()->{
                service.sayHi("lagou");
            });

            threadPool.submit(()->{
                service.sayHey("java");
            });

            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 启动打印线程
     * 每五秒打印一次最近一分钟tp90和tp99
     */
    private static void startPrintThead() {
        // 创建线程池，每五秒执行一次
        ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);

        scheduledExecutor.scheduleAtFixedRate(()->{
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String date = dtf2.format(now);

            // 加锁保证控制台打印样式
            synchronized (lock) {
                for (Map.Entry<String, ExpiringMap<Long, String>> entry : Common.get()) {
                    List<Long> tp90 = entry.getValue().keySet().stream().sorted(new Comparator<Long>() {
                        @Override
                        public int compare(Long o1, Long o2) {
                            return o2.compareTo(o1);
                        }
                    }).collect(Collectors.toList()).subList(0, Math.min(90, entry.getValue().size()));
                    StringBuilder sb = new StringBuilder(date).append(" ").append(entry.getKey()).append(" tp90(").append(tp90.size()).append("条记录):");
                    for (Long time : tp90) {
                        sb.append(" ").append(time);
                    }
                    System.out.println(sb.toString());
                }
                System.out.println();
            }
        }, 0, 5, TimeUnit.SECONDS);

        scheduledExecutor.scheduleAtFixedRate(()->{
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String date = dtf2.format(now);

            // 加锁保证控制台打印样式
            synchronized (lock) {
                for (Map.Entry<String, ExpiringMap<Long, String>> entry : Common.get()) {
                    List<Long> tp99 = entry.getValue().keySet().stream().sorted(new Comparator<Long>() {
                        @Override
                        public int compare(Long o1, Long o2) {
                            return o2.compareTo(o1);
                        }
                    }).collect(Collectors.toList()).subList(0, Math.min(99, entry.getValue().size()));
                    StringBuilder sb = new StringBuilder(date).append(" ").append(entry.getKey()).append(" tp99(").append(tp99.size()).append("条记录):");
                    for (Long time : tp99) {
                        sb.append(" ").append(time);
                    }
                    System.out.println(sb.toString());
                }
                System.out.println();
            }
        }, 0, 5, TimeUnit.SECONDS);
    }

    @Configuration
    @PropertySource("classpath:/dubbo-consumer.properties")
    //@EnableDubbo(scanBasePackages = "com.lagou.bean")
    @ComponentScan("com.lagou.bean")
    @EnableDubbo
    static class ConsumerConfiguration {

    }
}
